#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#import <libnotify/notify.h>

@interface DemoDelegate : NSObject <NSApplicationDelegate> {
    NSWindow *mainWindow;
}
- (void)playSound:(id)sender;
- (void)showNotification:(id)sender;
- (void)showNotificationWithMessage:(NSString *)message;
@end

@implementation DemoDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)notification {
    // 初始化 libnotify
    if (!notify_init("GNUstep Demo")) {
        NSLog(@"Failed to initialize libnotify");
        [NSApp terminate:nil];
    }

    // 创建主窗口
    NSRect windowFrame = NSMakeRect(100, 100, 300, 150);
    mainWindow = [[NSWindow alloc] initWithContentRect:windowFrame
                                            styleMask:NSWindowStyleMaskTitled | 
                                                     NSWindowStyleMaskClosable | 
                                                     NSWindowStyleMaskResizable
                                              backing:NSBackingStoreBuffered
                                                defer:NO];
    [mainWindow setTitle:@"Sound & Notify Demo"];

    // 按钮容器视图
    NSView *contentView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 300, 150)];
    
    // 播放声音按钮（使用 GNUstep 兼容样式）
    NSButton *soundBtn = [[NSButton alloc] initWithFrame:NSMakeRect(50, 80, 200, 30)];
    [soundBtn setTitle:@"Play Sound"];
    [soundBtn setBezelStyle:NSRoundedBezelStyle];  // 兼容样式
    [soundBtn setTarget:self];
    [soundBtn setAction:@selector(playSound:)];
    [contentView addSubview:soundBtn];
    [soundBtn release];

    // 显示通知按钮
    NSButton *notifyBtn = [[NSButton alloc] initWithFrame:NSMakeRect(50, 40, 200, 30)];
    [notifyBtn setTitle:@"Show Notification"];
    [notifyBtn setBezelStyle:NSRoundRectBezelStyle];
    [notifyBtn setTarget:self];
    [notifyBtn setAction:@selector(showNotification:)];
    [contentView addSubview:notifyBtn];
    [notifyBtn release];

    [mainWindow setContentView:contentView];
    [contentView release];
    [mainWindow makeKeyAndOrderFront:nil];
}

// 使用系统命令 aplay 播放声音（彻底避开 audiolib 兼容问题）
- (void)playSound:(id)sender {
    // 系统默认 WAV 文件（确保存在，可替换为其他 WAV 文件）
    NSString *soundPath = @"/usr/share/sounds/alsa/Front_Center.wav";
    
    // 检查文件是否存在
    if (![[NSFileManager defaultManager] fileExistsAtPath:soundPath]) {
        NSLog(@"Sound file not found: %@", soundPath);
        [self showNotificationWithMessage:@"Sound file not found!"];
        return;
    }

    // 创建 NSTask 执行 aplay 命令
    NSTask *task = [[NSTask alloc] init];
    [task setLaunchPath:@"/usr/bin/aplay"];  // ALSA 播放工具路径
    [task setArguments:[NSArray arrayWithObjects:soundPath, nil]];  // 播放目标文件
    
    @try {
        [task launch];  // 执行命令
        [task waitUntilExit];  // 等待播放完成
        [self showNotificationWithMessage:@"Sound played successfully!"];
    } @catch (NSException *e) {
        NSLog(@"Failed to play sound: %@", e.reason);
        [self showNotificationWithMessage:@"Failed to play sound!"];
    }
    [task release];
}

// 显示系统通知（封装成通用方法）
- (void)showNotificationWithMessage:(NSString *)message {
    NotifyNotification *n = notify_notification_new(
        "GNUstep Demo",
        [message UTF8String],  // 转换为 C 字符串
        "dialog-information"
    );
    notify_notification_set_timeout(n, 5000);  // 5秒后关闭

    GError *error = NULL;
    if (!notify_notification_show(n, &error)) {
        NSLog(@"Notification error: %s", error->message);
        g_error_free(error);
    }
    g_object_unref(G_OBJECT(n));
}

// 直接显示通知（按钮回调）
- (void)showNotification:(id)sender {
    [self showNotificationWithMessage:@"Hello from GNUstep!"];
}

// 资源清理
- (void)dealloc {
    notify_uninit();
    [mainWindow release];
    [super dealloc];
}

@end

int main(int argc, const char **argv) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
    [NSApplication load];
    NSApplication *app = [NSApplication sharedApplication];
    DemoDelegate *delegate = [[DemoDelegate alloc] init];
    [app setDelegate:delegate];
    
    [app run];
    
    [delegate release];
    [pool release];
    return 0;
}
